#!/usr/bin/perl -w  # useful for syntax highlighting!

# If the application has a vmtype setting (indicating it is running a
# virtual machine, it will automatically call vm_probe for this
# type to see if it is running or not.

package clreqd_modules;

use strict;
use cldb;
use Data::Dumper;
use Sys::Hostname;
use Config;
use ipinterfaces;
use clnet qw(CLNET2_gen_ip_list);
use mnttab;
use File::Temp qw(tempfile);

#########################################################################
# 13.11.2007 - If the application is not relevant to this node then	#
# 	       ignore this request for this application.		#
#########################################################################

sub probe_app {
my %ARGS=@_;
my $rc;

	my $APP=$ARGS{APPLICATION};

	#################################################################
	# What we need to do is to check to see if the application	#
	# has any IP addresses, and if so we can then check for them	#
	# and if found assume the application is running.		#
	#################################################################

	my $CLDB=new cldb("$::ENV{TRUECL_CFG}/config.db");
	if(!defined($CLDB)) {
		return "ERROR Unable to config to 'config' database.";
	}
	my $res=$CLDB->get_rows("SELECT * FROM applications WHERE name = '$APP';");
	if(!defined($res->[0]->{name})) {
		return "ERROR Application '$APP' is not known on this node.";
	}

	#################################################################
	# Check this node is defined in the list of nodes, and if	#
	# not then return "OK NA".					#
	#################################################################

	if(!defined($res->[0]->{nodes})) {
		$CLDB->disconnect;
		return "OK NA";
	}
	{
		my $h=hostname;
		my @F=split(/,/,$res->[0]->{nodes});
		if(! grep {$_ eq $h} @F) {
			$CLDB->disconnect;
			return "OK NA";
		}
	}

	#################################################################
	# Virtual machine; so let that decide whether it is up not	#
	# IP information or Volume information.				#
	#################################################################

	if(defined($res->[0]->{vmtype}) && length($res->[0]->{vmtype})) {
		return vm_probe(TYPE => $res->[0]->{vmtype}, NAME => $APP)
	}
	$res=$CLDB->get_rows("SELECT * FROM application_ips WHERE name = '$APP';");
	my $res2=$CLDB->get_rows("SELECT * FROM application_fs WHERE name = '$APP';");
	my $res3=$CLDB->get_rows("SELECT * FROM custom_app_probes WHERE name = '$APP';");
	$CLDB->disconnect; $CLDB=undef;
	if(!defined($res->[0]->{name}) && !defined($res2->[0]->{name}) &&
		!defined($res3->[0]->{name})) {
		# Application has no IPS, no file systems and no custom probe,
		# so nothing can be done to check for application.
		return "OK DOWN2";
	}

	#################################################################
	# Probe for IPs first if any exist.				#
	#################################################################

	if(defined($res->[0]->{ips})) {
		my $x;
		my $inters=new ipinterfaces();
		for (@$res) {
			$x=$_->{ips};
			next if !defined($x);
			my ($ips,$nm)=CLNET2_gen_ip_list($x);
			next if !length($ips);
			my $z;
			for $z (split(/,/,$ips)) {
				my $i=$inters->get_interface(ip=>$z);
				if(defined($i)) {
					return "OK UP";
				}
			}
		}
	}

	#################################################################
	# No IP's configured or matched, so look for mounted file	#
	# systems...							#
	#################################################################

	my $mnt=new mnttab;
	if(defined($res2->[0]->{mountpnt})) {
		my $x;
		for (@$res2) {
			$x=$_->{mountpnt};
			next if !defined($x);
			my $z=$mnt->get_from_fs($x);
			next if !defined($z);
			if(defined($_->{vg}) && defined($_->{lv}) &&
				$_->{vg} eq $z->{VG} && $_->{lv} eq $z->{LV}) {
				return "OK UP";
			}
		}
	}

	#################################################################
	# If a custom application probe exists, now is the time to	#
	# use it.							#
	#################################################################

	if(defined($res3->[0]->{script})) {
		my $d=$res3->[0]->{script};
		$d=pack("h*",$d);
		my ($fdd,$filename)=tempfile();
		if(! print $fdd $d) {
			return "ERROR Unable to write to temporary file.";
			close($fdd);
			unlink($filename);
		}
		close($fdd);
		chmod(0700,$filename);
		my $r=`$filename $APP test 2>&1`;
		unlink($filename);
		chomp $r;
		if($r eq "UP") {
			return "OK UP";
		}
	}

	return "OK DOWN";
}

1;
